import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.util.List;
import java.util.Map;

import com.speljohan.rsbot.bot.Bot;
import com.speljohan.rsbot.event.listeners.PaintListener;
import com.speljohan.rsbot.script.Constants;
import com.speljohan.rsbot.script.Script;
import com.speljohan.rsbot.script.wrappers.RSInterface;
import com.speljohan.rsbot.script.wrappers.RSInterfaceChild;
import com.speljohan.rsbot.script.wrappers.RSNPC;
import com.speljohan.rsbot.script.wrappers.RSTile;

public class XPestControl extends Script implements PaintListener {
	int attacking;
	int fightMode;
	int fightMode2;
	int FromThisPointX;
	int FromThisPointY;
	int Location;
	int BOAT;
	int TYPE;
	int WHERE = 0;
	int INTERGER1;
	int INTERGER2;
	int INTERGER3;
	int INTERGER4;
	int KNIGHTID;
	Point screenLoc = null;
	int LOST = 0;
	int WIN = 0;
	int LOSS = 0;
	int ran = random(11, 13);
	int CURRENTPOINTS = 0;
	int AMOUNT = 249;
	int GATE_CLOSED[] = { 14235, 14233, 14239, 14237 };
	int VOID_KNIGHT[] = { 3782, 3785, 3784, 7203 };
	int Portals[] = { 6150, 6151, 6152, 6153, 6142, 6143, 6144, 6145 };
	boolean doingspec = false;
	boolean SPEND = false;
	RSTile THIS_TILE;
	RSTile[] ToBoat;
	RSTile[] ToExchange;
	RSTile BOAT_TILE;

	long startTime = System.currentTimeMillis();
	long time = System.currentTimeMillis();

	Color BG = new Color(0, 0, 0, 125);

	private boolean ATTACKNPC(final RSNPC npc, final String action) { // edited
		// ruskis
		// a lil
		final RSTile tile = npc.getLocation();
		final RSTile randomTile = tile.randomizeTile(1, 1);
		try {
			final int hoverRand = random(8, 13);
			for (int i = 0; i < hoverRand; i++) {
				final Point screenLoc = npc.getScreenLocation();
				if (!pointOnScreen(screenLoc)
						&& getMyPlayer().getInteracting() == null) {
					walkTileMM(randomTile);
					return true;
				}

				moveMouse(screenLoc, 15, 15);

				final List<String> menuItems = getMenuItems();
				if (menuItems.isEmpty() || menuItems.size() <= 1) {
					continue;
				}
				if (menuItems.get(0).contains(npc.getName())
						&& getMyPlayer().getInteracting() == null) {
					clickMouse(true);
					return true;
				} else {
					for (int a = 1; a < menuItems.size(); a++) {
						if (menuItems.get(a).toLowerCase().contains(
								npc.getName().toLowerCase())
								&& getMyPlayer().getInteracting() == null) {
							clickMouse(false);
							return atMenu(action);
						}
					}
				}
			}

		} catch (final Exception e) {
			log("ATTACKNPC(RSNPC, String) error: " + e);
			return false;
		}
		return false;
	}

	void DOOR_OPENED() {
		if (findObject(GATE_CLOSED) != null
				&& distanceTo(findObject(GATE_CLOSED)) <= 3) {
			setCompass('N');
			setCameraAltitude(false);
			FINAL();
		} else {
			wait(random(50, 100));
		}
	}

	void DOOR_OPENED2() {
		if (findObject(GATE_CLOSED) != null
				&& distanceTo(findObject(GATE_CLOSED)) <= 3) {
			setCompass('e');
			setCameraAltitude(false);
			FINAL();
		} else {
			wait(random(50, 100));
		}
	}

	void DOOR_OPENED3() {
		if (findObject(GATE_CLOSED) != null
				&& distanceTo(findObject(GATE_CLOSED)) <= 3) {
			setCompass('e');
			setCameraAltitude(false);
			FINAL();
		} else {
			wait(random(50, 100));
		}
	}

	void DOORCHECK() {
		if (findObject(GATE_CLOSED) != null) {
			final int GET_Y = getNearestNPCByID(VOID_KNIGHT).getLocation()
					.getY();
			final int GET_X = getNearestNPCByID(VOID_KNIGHT).getLocation()
					.getX();
			walkTileMM(new RSTile(GET_X, GET_Y - 7));
			FINAL();
		} else {
			wait(random(50, 100));
		}
	}

	void doSpec() {
		if (getSpec() == 1000 && !specEnabled() && doingspec) {
			openTab(Constants.TAB_ATTACK);
			clickMouse(645 + random(0, 4), 425 + random(0, 4), true);
			wait(random(500, 1000));
		} else {
			wait(random(1, 3));
		}
	}

	public int extract(final String s) { // Taken from SmartPC
		int j = s.length() - 1;
		while (j >= 0 && Character.isDigit(s.charAt(j))) {
			j--;
		}
		return Integer.parseInt(s.substring(j + 1, s.length()));
	}

	void FINAL() {
		if (findObject(GATE_CLOSED) != null) {
			final int q = findObject(GATE_CLOSED).getLocation().getX();
			final int w = findObject(GATE_CLOSED).getLocation().getY();
			atTile(new RSTile(q, w), "Open");
		} else {
			wait(random(1, 2));
		}
	}

	@Override
	public String getAuthor() {
		return "Killa";
	}

	@Override
	public String getName() {
		return "XPestControl";
	}

	public String getScriptCategory() {
		return "Combat";
	}

	@Override
	public String getScriptDescription() {
		String html = "";
		html += "<html>";
		html += "<head>";
		html += "<style type=\"text/css\"> hr {color: white} p {margin-left: 20px}</style>";
		html += "</head>";
		html += "<body>";
		html += "<center>";
		html += "<b><font size=\"6\" color=\"red\">" + getName() + " v"
				+ getVersion() + " c" + "</font></b><br>";
		html += "<font size=\"3\" color=\"red\">Start at Bank or at boat.<br></font>";
		html += "</center>";
		html += "<center><table border=\"0\"><tr><td colspan=\"5\"><center><font size=6><b>== Options and Settings ==</b></font></center></td></tr><tr><td colspan=4><hr></td></tr><tbody><tr><td width=\"135\">";
		html += "<b>Spend?:</b></td><td width=\"140\"><center><input type=\"checkbox\" name=\"Spen\" value=\"true\" checked=\"checked\">&nbsp<b>Yes</b></center></td><td width=\"135\"></b></center></td></tr>";
		html += "<b>Use Special:</b></td><td width=\"140\"><center><input type=\"checkbox\" name=\"spec\" value=\"true\" checked=\"checked\">&nbsp<b>Yes</b></center></td><td width=\"135\"></b></center></td></tr>";
		html += "<b>Type of game:</b></td><td width=\"140\"><center>";
		html += "<td><center><select name=\"Game\"><option>Novice<option selected>Intermediate<option>Expert<option ></center></td></tr>";
		html += "<b>Exchanging for(Will exchange at 100 if Spend is checked):</b></td><td width=\"140\"><center>";
		html += "<td><center><select name=\"Exchange\"><option>Strength<option selected>Attack<option>Defence<option>Prayer<option>Magic<option>Range<option>Hit Points<option></center></td></tr>";
		html += "<b>Will train:</b></td><td width=\"140\"><center>";
		html += "<td><center><select name=\"attT\"><option>Strength<option selected>Attack<option>Defense<option ></center></td></tr>";
		html += "<tr><td colspan=2><b><font size=\"3\">&nbsp&nbsp X Series by Killa!</font></b></td><td  colspan=\"2\" align=right>"
				+ getVersion() + " &nbsp&nbsp</td></tr></table>";
		html += "</center></body>";
		html += "</html>";
		return html;
	}

	public int getSpec() {
		return getSetting(300);
	}

	public double getVersion() {
		return 1.1;
	}

	public int loop() {
		ToExchange = reversePath(ToBoat);
		setFightMode(fightMode);
		setCompass('N');
		setCameraAltitude(true);
		if (getEnergy() > random(60, 100) && !isRunning()) {
			setRun(true);
		}
		if (getMyPlayer().isMoving()) {
			return random(0, 150);
		}
		if (getNearestNPCByID(KNIGHTID) != null && ONBOAT()) {
			final RSInterfaceChild POINTS = RSInterface.getChildInterface(407,
					16);
			final String text = POINTS.getText();
			CURRENTPOINTS = extract(text);
		}
		if (getNearestNPCByID(KNIGHTID) != null && !ONBOAT()
				&& CURRENTPOINTS < AMOUNT && findObject(BOAT) != null
				&& distanceTo(findObject(BOAT)) < 6) {
			WHERE = 0;
			wait(random(2500, 3000));
			WIN_CHECK();
			wait(random(250, 500));
			atObject(findObject(BOAT), "Cross");
		}
		if (distanceTo(findObject(BOAT)) > 6 && !ONBOAT()
				&& CURRENTPOINTS < AMOUNT && !interfaceExists(242)
				&& !interfaceExists(211) && !interfaceExists(243)
				&& findObject(41512) != null) {
			walkPathMM(randomizePath(ToBoat, 2, 2), 20);
		}
		if (CURRENTPOINTS >= AMOUNT && !ONBOAT() && SPEND && BOAT != 14315) {
			walkPathMM(randomizePath(ToExchange, 2, 2), 20);
		}
		if (CURRENTPOINTS >= AMOUNT && !ONBOAT() && SPEND && BOAT == 14315
				&& distanceTo(findObject(BOAT)) < 5) {
			clickMouse(646, 49, 3, 3, true);
		}
		if (getNearestNPCByID(VOID_KNIGHT) != null
				&& getNearestNPCByID(3788) == null
				&& !ONBOAT()
				&& findObject(GATE_CLOSED) != null
				&& distanceTo(new RSTile(getNearestNPCByID(VOID_KNIGHT)
						.getLocation().getX(), getNearestNPCByID(VOID_KNIGHT)
						.getLocation().getY() - 7)) <= 2
				&& getNearestNPCByID(VOID_KNIGHT).getLocation().getY() >= getMyPlayer()
						.getLocation().getY()
				&& getMyPlayer().getInteracting() == null) {
			final int GET_Y = getNearestNPCByID(VOID_KNIGHT).getLocation()
					.getY();
			final int GET_X = getNearestNPCByID(VOID_KNIGHT).getLocation()
					.getX();
			FromThisPointX = GET_X;
			FromThisPointY = GET_Y;
			walkTileMM(new RSTile(GET_X, GET_Y - 7));
			DOOR_OPENED();
			walkTileMM(new RSTile(getMyPlayer().getLocation().getX() - 7,
					getMyPlayer().getLocation().getY() - 10));
			wait(random(2000, 2500));
		}
		if (CURRENTPOINTS >= AMOUNT && AMOUNT != 100) {
			log("Have near 249 points, Will log out.");
			logout();
			stopAllScripts();
		}
		if (getNearestNPCByID(3788) != null && CURRENTPOINTS > 100 && SPEND) {
			SpendingPoints();
			log("Points Spent");
		}
		if (getNearestNPCByID(3788) != null && CURRENTPOINTS < AMOUNT
				&& distanceTo(BOAT_TILE) > 5) {
			walkPathMM(randomizePath(ToBoat, 2, 2), 20);
		}
		if (getNearestNPCByID(3788) == null
				&& !ONBOAT()
				&& getNearestNPCByID(KNIGHTID) == null
				&& distanceTo(findObject(14256)) <= 6
				&& getNearestNPCByID(3781).getLocation().getY() <= getMyPlayer()
						.getLocation().getY() && WHERE == 0) {
			final int OUT_OF_BOATY = getMyPlayer().getLocation().getY() - ran;
			final int OUT_OF_BOATX = getMyPlayer().getLocation().getX();
			walkTileMM(new RSTile(OUT_OF_BOATX, OUT_OF_BOATY));
			log("Assuming: Player is in game.");
		}
		if (getNearestNPCByID(VOID_KNIGHT) != null
				&& getNearestNPCByID(VOID_KNIGHT).getLocation().getY() <= getMyPlayer()
						.getLocation().getY() && WHERE == 0) {
			final int GET_Y = getNearestNPCByID(VOID_KNIGHT).getLocation()
					.getY();
			final int GET_X = getNearestNPCByID(VOID_KNIGHT).getLocation()
					.getX();
			walkTileMM(new RSTile(GET_X, GET_Y - 7));
			wait(random(2500, 4000));
			final int GETMYX = getMyPlayer().getLocation().getX();
			final int GETMYY = getMyPlayer().getLocation().getY();
			DOORCHECK();
			walkTileMM(new RSTile(GETMYX - random(7, -7), GETMYY - 10));
			wait(random(2000, 2500));
		}
		if (getNearestNPCByID(3788) == null
				&& !ONBOAT()
				&& getNearestNPCByName("Shifter", "Defiler", "Torcher",
						"Brawler", "Ravager") != null
				&& getNearestNPCByID(KNIGHTID) == null
				&& getMyPlayer().getInteracting() == null) {
			ATTACKNPC(getNearestNPCByName("Shifter", "Defiler", "Torcher",
					"Brawler", "Ravager", "Spinner"), "Attack");
			doSpec();
			WHERE = 1;
		}
		if (WHERE == 1
				&& getNearestNPCByName("Shifter", "Defiler", "Torcher",
						"Brawler", "Ravager") == null
				&& findObject(BOAT) == null && getNearestNPCByID(3781) == null) {
			walkTo(getMyPlayer().getLocation().getX() - 2, getMyPlayer()
					.getLocation().getY() + 7);
			log("Attempting To Find more Monsters.");
		}
		if (getNearestNPCByID(VOID_KNIGHT) != null
				&& getNearestNPCByID(3788) == null && !ONBOAT()
				&& findObject(14210) != null
				&& distanceTo(findObject(14210)) == 1) {
			log("Something stupid is going on.");
			walkTileMM(new RSTile(getNearestNPCByID(VOID_KNIGHT).getLocation()
					.getX(), getNearestNPCByID(VOID_KNIGHT).getLocation()
					.getY() - 7));
			final int GETMYX = getMyPlayer().getLocation().getX();
			final int GETMYY = getMyPlayer().getLocation().getY();
			DOORCHECK();
			walkTileMM(new RSTile(GETMYX - 7, GETMYY - 10));
			wait(random(2000, 2500));

		}
		if (getNearestNPCByID(VOID_KNIGHT) != null
				&& getNearestNPCByID(3788) == null
				&& !ONBOAT()
				&& findObject(GATE_CLOSED) != null
				&& distanceTo(new RSTile(getNearestNPCByID(VOID_KNIGHT)
						.getLocation().getX() + 14, getNearestNPCByID(
						VOID_KNIGHT).getLocation().getY())) <= 1
				&& getNearestNPCByID(VOID_KNIGHT).getLocation().getY() >= getMyPlayer()
						.getLocation().getY()) {
			final int GET_Y = getNearestNPCByID(VOID_KNIGHT).getLocation()
					.getY();
			final int GET_X = getNearestNPCByID(VOID_KNIGHT).getLocation()
					.getX();
			walkTileMM(new RSTile(GET_X + 14, GET_Y));
			wait(random(500, 1000));
			DOOR_OPENED2();
			final int GETMYX = getMyPlayer().getLocation().getX();
			final int GETMYY = getMyPlayer().getLocation().getY();
			walkTileMM(new RSTile(GETMYX - 3, GETMYY - 5));
			wait(random(2000, 2500));
		}
		if (getNearestNPCByID(VOID_KNIGHT) != null) {
			if (getNearestNPCByID(3788) == null
					&& !ONBOAT()
					&& findObject(GATE_CLOSED) != null
					&& distanceTo(new RSTile(getNearestNPCByID(VOID_KNIGHT)
							.getLocation().getX() - 14, getNearestNPCByID(
							VOID_KNIGHT).getLocation().getY())) <= 1
					&& getNearestNPCByID(VOID_KNIGHT).getLocation().getY() >= getMyPlayer()
							.getLocation().getY()) {
				final int GET_Y = getNearestNPCByID(VOID_KNIGHT).getLocation()
						.getY();
				final int GET_X = getNearestNPCByID(VOID_KNIGHT).getLocation()
						.getX();
				walkTileMM(new RSTile(GET_X - 14, GET_Y - 7));
				wait(random(500, 1000));
				DOOR_OPENED3();
				final int GETMYX = getMyPlayer().getLocation().getX();
				final int GETMYY = getMyPlayer().getLocation().getY();
				walkTileMM(new RSTile(GETMYX - 3, GETMYY - 5));
				wait(random(2000, 2500));
			}
		}
		return random(20, 50);
	}

	public boolean ONBOAT() {
		final RSTile myLocation = getMyPlayer().getLocation();
		final int myX = myLocation.getX();
		final int myY = myLocation.getY();

		if (myX <= INTERGER1 && myX >= INTERGER2 && myY >= INTERGER3
				&& myY <= INTERGER4) {
			return true;
		}

		return false;
	}

	public void onFinish() {
		Bot.getEventManager().removeListener(PaintListener.class, this);
	}

	public void onRepaint(final Graphics g) {
		if (isLoggedIn()) {
			long millis = System.currentTimeMillis() - startTime;
			final long hours = millis / (1000 * 60 * 60);
			millis -= hours * 1000 * 60 * 60;
			final long minutes = millis / (1000 * 60);
			millis -= minutes * 1000 * 60;
			final long seconds = millis / 1000;
			g.setColor(BG);
			g.fill3DRect(9, 210, 170, 120, true);
			g.setColor(Color.white);
			g.drawString("XPestControl by Killa", 18, 230);
			g.drawString("EXP Gained: "
					+ (skills.getCurrentSkillExp(fightMode2) - attacking), 18,
					250);
			g.drawString("EXP To next lvl: "
					+ skills.getXPToNextLevel(fightMode2), 18, 270);
			g.drawString("Wins: " + WIN + " Points Gained:" + WIN * TYPE, 18,
					290);
			g.drawString("Loss / Lacked:" + LOSS + "/" + LOST, 18, 310);
			g.drawString("Running for: " + hours + "h " + minutes + "m "
					+ seconds + "s", 18, 330);
		}
	}

	public boolean onStart(final Map<String, String> args) {
		if (args.get("Game").equals("Novice")) {
			ToBoat = new RSTile[] { new RSTile(2660, 2649),
					new RSTile(2657, 2639) };
			BOAT_TILE = new RSTile(2657, 2639);
			BOAT = 14315;
			INTERGER1 = 2663;
			INTERGER2 = 2660;
			INTERGER3 = 2638;
			INTERGER4 = 2643;
			KNIGHTID = 3802;
			TYPE = 2;
		}
		if (args.get("Game").equals("Intermediate")) {
			ToBoat = new RSTile[] { new RSTile(2658, 2649),
					new RSTile(2644, 2644) };
			BOAT_TILE = new RSTile(2644, 2644);
			BOAT = 25631;
			INTERGER1 = 2641;
			INTERGER2 = 2638;
			INTERGER3 = 2642;
			INTERGER4 = 2647;
			KNIGHTID = 6140;
			TYPE = 3;
		}
		if (args.get("Game").equals("Expert")) {
			ToBoat = new RSTile[] { new RSTile(2659, 2649),
					new RSTile(2648, 2646), new RSTile(2638, 2653) };
			BOAT_TILE = new RSTile(2638, 2653);
			BOAT = 25632;
			INTERGER1 = 2635; // highest x
			INTERGER2 = 2632; // lowest x
			INTERGER3 = 2649; // lowest y
			INTERGER4 = 2654; // highest y
			KNIGHTID = 6141;
			TYPE = 4;
		}
		if (args.get("Exchange").equals("Strength")) {
			Location = 1;
		}
		if (args.get("Exchange").equals("Attack")) {
			Location = 2;
		}
		if (args.get("Exchange").equals("Defense")) {
			Location = 3;
		}
		if (args.get("Exchange").equals("Range")) {
			Location = 4;
		}
		if (args.get("Exchange").equals("Prayer")) {
			Location = 5;
		}
		if (args.get("Exchange").equals("Magic")) {
			Location = 6;
		}
		if (args.get("Exchange").equals("Hit Points")) {
			Location = 7;
		}
		if (args.get("attT").equals("Strength")) {
			attacking = skills.getCurrentSkillExp(2);
			fightMode = 1;
		}
		if (args.get("attT").equals("Attack")) {
			attacking = skills.getCurrentSkillExp(0);
			fightMode = 0;
		}
		if (args.get("spec") != null) {
			if (args.get("spec").equals("true")) {
				doingspec = true;
			}
		}
		if (args.get("Spen") != null) {
			if (args.get("Spen").equals("true")) {
				SPEND = true;
				AMOUNT = 100;
			}
		}
		if (args.get("attT").equals("Defence")) {
			attacking = skills.getCurrentSkillExp(1);
			fightMode = 3;
		}
		if (fightMode == 3) {
			fightMode2 = 1;
		}
		if (fightMode == 0) {
			fightMode2 = 0;
		}
		if (fightMode == 1) {
			fightMode2 = 2;
		}
		return true;
	}

	boolean specEnabled() {
		return getSetting(301) == 1;
	}

	void SpendingPoints() {
		final int x = random(210, 304);
		final int y = random(288, 308);
		if (RSInterface.getInterface(267).isValid()) {
			if (Location == 1) {
				clickMouse(423, 70, true);
				wait(random(1000, 2000));
				clickMouse(x, y, true);
				CURRENTPOINTS = 0;
			} else if (Location == 2) {
				clickMouse(204, 71, true);
				wait(random(1000, 2000));
				clickMouse(x, y, true);
				CURRENTPOINTS = 0;
			} else if (Location == 3) {
				clickMouse(206, 108, true);
				wait(random(1000, 2000));
				clickMouse(x, y, true);
				CURRENTPOINTS = 0;
			} else if (Location == 4) {
				clickMouse(423, 110, true);
				wait(random(1000, 2000));
				clickMouse(x, y, true);
				CURRENTPOINTS = 0;
			} else if (Location == 5) {
				clickMouse(201, 186, true);
				wait(random(1000, 2000));
				clickMouse(x, y, true);
				CURRENTPOINTS = 0;
			} else if (Location == 6) {
				clickMouse(206, 146, true);
				wait(random(1000, 2000));
				clickMouse(x, y, true);
				CURRENTPOINTS = 0;
			} else if (Location == 7) {
				clickMouse(435, 147, true);
				wait(random(1000, 2000));
				clickMouse(x, y, true);
				CURRENTPOINTS = 0;
			}
		} else {
			atNPC(getNearestNPCByID(3788), "change");
			wait(random(1000, 2000));
		}
	}

	void WIN_CHECK() {
		if (interfaceExists(242)) { // From SmartPC
			LOSS++;
		} else if (interfaceExists(211)) {
			LOST++;
		} else if (interfaceExists(243)) {
			WIN++;
		}
		while (interfaceExists(242) || interfaceExists(211)
				|| interfaceExists(243)) {
			clickMouse(254 + random(0, 20), 455 + random(0, 4), true);
		}
	}
}